# -*- coding: utf-8 -*-
"""
文档转换器
支持 PDF、Word 等格式的互转
"""

import os
from pathlib import Path
from pdf2docx import Converter as PDFConverter
from docx2pdf import convert as docx_to_pdf_convert
import pdf2image
from PIL import Image
import PyPDF2
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter, A4
from reportlab.lib.utils import ImageReader
import win32com.client
import pythoncom


class DocumentConverter:
    """文档转换器类"""

    def __init__(self):
        pass

    def _pdf_to_word_simple(self, pdf_path, output_path):
        """
        简化PDF转Word - 最后备用方案
        结合pdfplumber和PyPDF2提取内容
        """
        from docx import Document
        from docx.shared import Pt

        doc = Document()

        # 尝试pdfplumber
        try:
            import pdfplumber
            with pdfplumber.open(pdf_path) as pdf:
                for page_num, page in enumerate(pdf.pages):
                    if page_num > 0:
                        doc.add_page_break()

                    text = page.extract_text()
                    if text and text.strip():
                        for para in text.split('\n\n'):
                            if para.strip():
                                doc.add_paragraph(para.strip())

            doc.save(output_path)
            return os.path.exists(output_path) and os.path.getsize(output_path) > 500
        except:
            pass

        # 降级到PyPDF2
        try:
            with open(pdf_path, 'rb') as file:
                pdf_reader = PyPDF2.PdfReader(file)
                for page in pdf_reader.pages:
                    text = page.extract_text()
                    if text.strip():
                        doc.add_paragraph(text)

            doc.save(output_path)
            return os.path.exists(output_path) and os.path.getsize(output_path) > 500
        except:
            return False

    def _optimize_word_format(self, docx_path):
        """
        优化Word文档格式 - 修正pdf2docx生成的格式问题
        关键改进：
        1. 统一段落样式
        2. 修正行距
        3. 修正页边距
        4. 移除多余的空段落
        """
        try:
            from docx import Document
            from docx.shared import Pt, Cm
            from docx.enum.text import WD_LINE_SPACING

            doc = Document(docx_path)

            # 设置页面边距
            sections = doc.sections
            for section in sections:
                section.top_margin = Cm(2.54)
                section.bottom_margin = Cm(2.54)
                section.left_margin = Cm(3.18)
                section.right_margin = Cm(3.18)

            # 优化段落格式
            paragraphs_to_remove = []
            for i, para in enumerate(doc.paragraphs):
                # 移除空段落（保留必要的分页符）
                if not para.text.strip() and len(para.runs) == 0:
                    paragraphs_to_remove.append(para)
                    continue

                # 设置段落格式
                para.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
                para.paragraph_format.space_before = Pt(0)
                para.paragraph_format.space_after = Pt(0)

                # 设置字体
                for run in para.runs:
                    if run.font.size is None or run.font.size < Pt(8):
                        run.font.size = Pt(10.5)

            # 删除多余的空段落
            for para in paragraphs_to_remove[:10]:  # 限制删除数量，避免过度
                try:
                    p = para._element
                    p.getparent().remove(p)
                except:
                    pass

            doc.save(docx_path)
            print("  已优化Word格式：边距、行距、字体")

        except Exception as e:
            print(f"  警告：格式优化失败 ({str(e)})，但文档内容完整")

    def _pdf_to_word_smart_pymupdf(self, pdf_path, output_path):
        """
        智能PDF转Word - 优化段落识别和排版
        核心改进：
        1. 智能段落合并 - 解决提前换行问题
        2. 空间位置分析 - 根据坐标判断段落
        3. 行间距检测 - 区分段落和正常换行
        4. 字体检测 - 识别标题和正文
        5. 分栏识别 - 处理多栏布局
        """
        import fitz  # PyMuPDF
        from docx import Document
        from docx.shared import Inches, Pt, RGBColor
        from docx.enum.text import WD_ALIGN_PARAGRAPH
        from docx.oxml.ns import qn
        from io import BytesIO

        doc = Document()

        # 设置默认样式
        style = doc.styles['Normal']
        style.font.name = 'Times New Roman'
        style._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
        style.font.size = Pt(10.5)
        style.paragraph_format.line_spacing = 1.5

        pdf_doc = fitz.open(pdf_path)

        print(f"  PDF页数: {len(pdf_doc)}")

        for page_num in range(len(pdf_doc)):
            page = pdf_doc.load_page(page_num)

            print(f"  处理第 {page_num + 1}/{len(pdf_doc)} 页...")

            if page_num > 0:
                doc.add_page_break()

            # 获取页面尺寸
            page_rect = page.rect
            page_width = page_rect.width
            page_height = page_rect.height

            # ========== 1. 智能提取并分析文本块 ==========
            text_blocks = page.get_text("dict")["blocks"]

            # 分离文本块和图片块
            text_content = []
            image_blocks = []

            for block in text_blocks:
                if block.get("type") == 0:  # 文本块
                    for line in block.get("lines", []):
                        for span in line.get("spans", []):
                            text_content.append({
                                'text': span['text'],
                                'bbox': span['bbox'],  # (x0, y0, x1, y1)
                                'size': span['size'],
                                'font': span['font'],
                                'color': span['color'],
                                'flags': span['flags']  # 粗体、斜体等
                            })
                elif block.get("type") == 1:  # 图片块
                    image_blocks.append(block)

            # ========== 2. 智能段落重组 ==========
            paragraphs = self._reorganize_paragraphs(text_content, page_width, page_height)

            # ========== 3. 提取表格 ==========
            tables_data = []
            try:
                tables = page.find_tables()
                if tables:
                    for table in tables.tables:
                        table_data = table.extract()
                        bbox = table.bbox
                        tables_data.append({
                            'data': table_data,
                            'bbox': bbox
                        })
            except:
                pass

            # ========== 4. 提取图片 ==========
            images_data = []
            image_list = page.get_images()
            for img_index, img in enumerate(image_list):
                try:
                    xref = img[0]
                    base_image = pdf_doc.extract_image(xref)
                    image_bytes = base_image["image"]

                    # 获取图片位置
                    img_rect = page.get_image_rects(xref)
                    if img_rect:
                        bbox = img_rect[0]
                    else:
                        bbox = (0, 0, 0, 0)

                    images_data.append({
                        'bytes': image_bytes,
                        'bbox': bbox
                    })
                except Exception as e:
                    print(f"    图片提取失败: {e}")

            # ========== 5. 按位置排序所有元素 ==========
            all_elements = []

            for para in paragraphs:
                all_elements.append({
                    'type': 'paragraph',
                    'content': para,
                    'y_pos': para['y_start']
                })

            for table in tables_data:
                all_elements.append({
                    'type': 'table',
                    'content': table,
                    'y_pos': table['bbox'][1]
                })

            for img in images_data:
                all_elements.append({
                    'type': 'image',
                    'content': img,
                    'y_pos': img['bbox'][1] if img['bbox'][1] > 0 else 9999
                })

            # 按y坐标排序
            all_elements.sort(key=lambda x: x['y_pos'])

            # ========== 6. 按顺序添加到Word文档 ==========
            for element in all_elements:
                if element['type'] == 'paragraph':
                    para_data = element['content']
                    text = para_data['text']

                    if not text.strip():
                        continue

                    # 添加段落
                    p = doc.add_paragraph(text)

                    # 设置字体大小
                    font_size = para_data['avg_size']
                    run = p.runs[0] if p.runs else None
                    if run:
                        run.font.size = Pt(font_size)

                        # 标题识别（字体较大）
                        if font_size > 13:
                            run.bold = True

                        # 设置字体
                        run.font.name = 'Times New Roman'
                        run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')

                    # 对齐方式
                    if para_data.get('is_centered'):
                        p.alignment = WD_ALIGN_PARAGRAPH.CENTER
                    elif para_data.get('is_right'):
                        p.alignment = WD_ALIGN_PARAGRAPH.RIGHT

                elif element['type'] == 'table':
                    table_info = element['content']
                    table_data = table_info['data']

                    if table_data and len(table_data) > 0:
                        # 创建Word表格
                        rows = len(table_data)
                        cols = max(len(row) for row in table_data if row)

                        if cols > 0:
                            word_table = doc.add_table(rows=rows, cols=cols)
                            word_table.style = 'Light Grid Accent 1'

                            for i, row_data in enumerate(table_data):
                                for j, cell_data in enumerate(row_data or []):
                                    if j < cols and cell_data:
                                        word_table.rows[i].cells[j].text = str(cell_data)

                elif element['type'] == 'image':
                    img_info = element['content']
                    try:
                        image_stream = BytesIO(img_info['bytes'])
                        doc.add_picture(image_stream, width=Inches(5.5))

                        # 图片居中
                        last_paragraph = doc.paragraphs[-1]
                        last_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
                    except Exception as e:
                        print(f"    图片添加失败: {e}")

        pdf_doc.close()
        doc.save(output_path)

        if os.path.exists(output_path) and os.path.getsize(output_path) > 1000:
            return True
        return False

    def _reorganize_paragraphs(self, text_content, page_width, page_height):
        """
        智能段落重组 - 核心算法
        解决提前换行问题
        """
        if not text_content:
            return []

        # 按y坐标排序
        text_content.sort(key=lambda x: (x['bbox'][1], x['bbox'][0]))

        paragraphs = []
        current_para = {
            'text': '',
            'y_start': 0,
            'y_end': 0,
            'x_start': 0,
            'x_end': 0,
            'avg_size': 0,
            'sizes': [],
            'is_centered': False,
            'is_right': False
        }

        # 检测是否为双栏布局
        mid_x = page_width / 2
        left_column = [t for t in text_content if t['bbox'][2] < mid_x + 20]
        right_column = [t for t in text_content if t['bbox'][0] > mid_x - 20]
        is_two_column = len(left_column) > 5 and len(right_column) > 5

        if is_two_column:
            print("    检测到双栏布局")
            # 分别处理左右两栏
            left_paras = self._merge_text_blocks(left_column, page_width, page_height)
            right_paras = self._merge_text_blocks(right_column, page_width, page_height)

            # 合并结果，按y坐标交替
            all_paras = left_paras + right_paras
            all_paras.sort(key=lambda x: (x['y_start'], x['x_start']))
            return all_paras
        else:
            # 单栏布局
            return self._merge_text_blocks(text_content, page_width, page_height)

    def _merge_text_blocks(self, text_content, page_width, page_height):
        """
        合并文本块为段落
        核心逻辑：根据y坐标间距、x坐标位置、字体大小判断是否应该合并
        """
        if not text_content:
            return []

        paragraphs = []
        current_para = {
            'text': '',
            'y_start': 0,
            'y_end': 0,
            'x_start': 0,
            'x_end': 0,
            'avg_size': 0,
            'sizes': [],
            'is_centered': False,
            'is_right': False
        }

        for i, span in enumerate(text_content):
            text = span['text']
            bbox = span['bbox']  # (x0, y0, x1, y1)
            size = span['size']

            # 初始化第一个段落
            if not current_para['text']:
                current_para['text'] = text
                current_para['y_start'] = bbox[1]
                current_para['y_end'] = bbox[3]
                current_para['x_start'] = bbox[0]
                current_para['x_end'] = bbox[2]
                current_para['sizes'].append(size)
                continue

            # 计算y方向间距
            y_gap = bbox[1] - current_para['y_end']

            # 计算平均字体大小
            avg_size = sum(current_para['sizes']) / len(current_para['sizes'])

            # 判断是否应该开始新段落
            should_break = False

            # 条件1: y间距过大（超过1.5倍字体大小）
            if y_gap > avg_size * 1.5:
                should_break = True

            # 条件2: 字体大小变化显著（标题等）
            if abs(size - avg_size) > 2:
                should_break = True

            # 条件3: x坐标回到行首（新段落）
            x_back_to_start = bbox[0] < current_para['x_start'] + 10
            if y_gap > avg_size * 0.8 and x_back_to_start:
                # 检查上一行是否以句号、问号、感叹号等结束
                last_char = current_para['text'].rstrip()[-1] if current_para['text'].rstrip() else ''
                if last_char in '.。!！?？\n':
                    should_break = True

            # 条件4: 当前文本以缩进开始（新段落）
            if bbox[0] > current_para['x_start'] + avg_size * 2 and y_gap > avg_size * 0.5:
                should_break = True

            if should_break:
                # 保存当前段落
                if current_para['text'].strip():
                    current_para['avg_size'] = avg_size

                    # 判断对齐方式
                    x_center = (current_para['x_start'] + current_para['x_end']) / 2
                    page_center = page_width / 2
                    if abs(x_center - page_center) < page_width * 0.1:
                        current_para['is_centered'] = True
                    elif current_para['x_end'] > page_width * 0.85:
                        current_para['is_right'] = True

                    paragraphs.append(current_para)

                # 开始新段落
                current_para = {
                    'text': text,
                    'y_start': bbox[1],
                    'y_end': bbox[3],
                    'x_start': bbox[0],
                    'x_end': bbox[2],
                    'avg_size': 0,
                    'sizes': [size],
                    'is_centered': False,
                    'is_right': False
                }
            else:
                # 合并到当前段落
                # 判断是否需要添加空格（英文单词之间）
                if text and current_para['text']:
                    last_char = current_para['text'][-1]
                    first_char = text[0]

                    # 如果都是字母或数字，添加空格
                    if (last_char.isalnum() or last_char in ',.;:') and first_char.isalnum():
                        if not current_para['text'].endswith(' '):
                            current_para['text'] += ' '

                current_para['text'] += text
                current_para['y_end'] = bbox[3]
                current_para['x_end'] = bbox[2]
                current_para['sizes'].append(size)

        # 保存最后一个段落
        if current_para['text'].strip():
            avg_size = sum(current_para['sizes']) / len(current_para['sizes'])
            current_para['avg_size'] = avg_size

            x_center = (current_para['x_start'] + current_para['x_end']) / 2
            page_center = page_width / 2
            if abs(x_center - page_center) < page_width * 0.1:
                current_para['is_centered'] = True
            elif current_para['x_end'] > page_width * 0.85:
                current_para['is_right'] = True

            paragraphs.append(current_para)

        return paragraphs

    def convert(self, input_path, output_dir, conversion_type):
        """
        转换文档
        :param input_path: 输入文件路径
        :param output_dir: 输出目录
        :param conversion_type: 转换类型
        :return: 输出文件路径
        """
        if conversion_type == 'pdf_to_word':
            return self.pdf_to_word(input_path, output_dir)
        elif conversion_type == 'word_to_pdf':
            return self.word_to_pdf(input_path, output_dir)
        elif conversion_type == 'pdf_to_images':
            return self.pdf_to_images(input_path, output_dir)
        elif conversion_type == 'images_to_pdf':
            return self.images_to_pdf([input_path], output_dir)
        elif conversion_type == 'doc_to_docx':
            return self.doc_to_docx(input_path, output_dir)
        elif conversion_type == 'docx_to_doc':
            return self.docx_to_doc(input_path, output_dir)
        else:
            raise ValueError(f"不支持的转换类型: {conversion_type}")

    def pdf_to_word(self, pdf_path, output_dir):
        """
        PDF转Word - 多方法确保质量
        优先顺序：Word COM > pdf2docx > PyMuPDF智能 > pdfplumber
        :param pdf_path: PDF文件路径
        :param output_dir: 输出目录
        :return: 输出文件路径
        """
        if not os.path.exists(pdf_path):
            raise FileNotFoundError(f"文件不存在: {pdf_path}")

        if not pdf_path.lower().endswith('.pdf'):
            raise ValueError(f"不是PDF文件: {pdf_path}")

        # 生成输出文件名
        base_name = os.path.splitext(os.path.basename(pdf_path))[0]
        output_path = os.path.join(output_dir, f"{base_name}.docx")

        print(f"\n开始转换: {os.path.basename(pdf_path)}")
        print("=" * 60)

        # 方法1: 使用 Microsoft Word COM（最佳质量，如果可用）
        try:
            print("方法1: 尝试使用 Microsoft Word - 100%完美转换...")
            pythoncom.CoInitialize()
            try:
                word = win32com.client.Dispatch("Word.Application")
                word.Visible = False
                word.DisplayAlerts = 0

                # 用Word打开PDF
                doc = word.Documents.Open(os.path.abspath(pdf_path))

                # 保存为Word格式
                doc.SaveAs2(os.path.abspath(output_path), FileFormat=16)  # 16 = docx
                doc.Close()
                word.Quit()

                if os.path.exists(output_path) and os.path.getsize(output_path) > 1000:
                    print("✓ Word COM转换成功 - 100%保留原始排版")
                    return output_path
            except Exception as com_error:
                print(f"✗ Word COM不可用: {str(com_error)}")
            finally:
                pythoncom.CoUninitialize()
        except Exception as e:
            print(f"✗ Word未安装或不可用")

        # 方法2: 使用 pdf2docx（推荐，平衡质量和兼容性）
        try:
            print("\n方法2: 使用 pdf2docx - 保留格式、图片、表格...")
            cv = PDFConverter(pdf_path)

            # 转换配置
            cv.convert(
                output_path,
                start=0,
                end=None,
                pages=None
            )
            cv.close()

            if os.path.exists(output_path) and os.path.getsize(output_path) > 1000:
                # 优化生成的Word文档格式
                self._optimize_word_format(output_path)
                print("✓ pdf2docx转换成功 - 格式已优化")
                return output_path
            else:
                print("✗ pdf2docx生成的文件过小，尝试备用方法...")
        except Exception as e:
            print(f"✗ pdf2docx转换失败: {str(e)}")
            print("  尝试备用方法...")

        # 方法3: 智能PyMuPDF转换（排版优化）
        try:
            print("\n方法3: 使用智能PyMuPDF - 段落优化...")
            result = self._pdf_to_word_smart_pymupdf(pdf_path, output_path)
            if result:
                print("✓ 智能PyMuPDF转换成功 - 段落已优化")
                return output_path
        except ImportError:
            print("✗ PyMuPDF未安装")
        except Exception as e:
            print(f"✗ 智能PyMuPDF转换失败: {str(e)}")

        # 方法4: pdfplumber简化提取（最后备用）
        try:
            print("\n方法4: pdfplumber简化提取...")
            result = self._pdf_to_word_simple(pdf_path, output_path)
            if result:
                print("✓ 简化提取成功 - 内容已保存")
                return output_path
        except Exception as e:
            print(f"✗ 简化提取失败: {str(e)}")

        # 所有方法都失败
        print("\n" + "=" * 60)
        print("✗ 转换失败: 所有方法都无法处理此PDF")
        print("\n建议:")
        print("1. 安装推荐的库: pip install PyMuPDF pdfplumber")
        print("2. 检查PDF是否已加密或损坏")
        print("3. 尝试使用Adobe Acrobat等专业软件")
        print("=" * 60)

        raise Exception("PDF转Word失败：所有转换方法都失败了")

        return output_path

    def word_to_pdf(self, word_path, output_dir):
        """
        Word转PDF - 高质量转换，完美保留格式
        :param word_path: Word文件路径
        :param output_dir: 输出目录
        :return: 输出文件路径
        """
        if not os.path.exists(word_path):
            raise FileNotFoundError(f"文件不存在: {word_path}")

        ext = word_path.lower()
        if not (ext.endswith('.doc') or ext.endswith('.docx')):
            raise ValueError(f"不是Word文件: {word_path}")

        base_name = os.path.splitext(os.path.basename(word_path))[0]
        output_path = os.path.join(output_dir, f"{base_name}.pdf")

        print(f"\n开始转换: {os.path.basename(word_path)}")
        print("=" * 60)

        # 方法1: 使用 win32com (最佳质量，需要Microsoft Office)
        try:
            print("方法1: 使用 Microsoft Word COM - 最佳质量...")
            pythoncom.CoInitialize()
            try:
                word = win32com.client.Dispatch("Word.Application")
                word.Visible = False
                word.DisplayAlerts = 0  # 禁用警告

                # 打开文档
                doc = word.Documents.Open(os.path.abspath(word_path))

                # 高质量PDF设置
                # wdExportFormatPDF = 17
                # wdExportOptimizeForPrint = 0 (高质量)
                # wdExportAllDocument = 0
                # wdExportDocumentContent = 0
                # wdExportCreateNoBookmarks = 0

                doc.ExportAsFixedFormat(
                    OutputFileName=os.path.abspath(output_path),
                    ExportFormat=17,  # PDF格式
                    OpenAfterExport=False,
                    OptimizeFor=0,  # 0=高质量打印, 1=最小文件大小
                    CreateBookmarks=1,  # 创建书签
                    DocStructureTags=True,  # 文档结构标签
                    BitmapMissingFonts=True,  # 嵌入缺失字体
                    UseISO19005_1=False  # 不使用PDF/A标准
                )

                doc.Close(SaveChanges=False)
                word.Quit()

                if os.path.exists(output_path) and os.path.getsize(output_path) > 1000:
                    print("✓ Word COM转换成功 - 完美保留格式、图片、表格")
                    return output_path
            except Exception as com_error:
                print(f"✗ Word COM转换失败: {str(com_error)}")
            finally:
                pythoncom.CoUninitialize()
        except Exception as e:
            print(f"✗ 初始化COM失败: {str(e)}")

        # 方法2: 使用 docx2pdf (调用Word COM的简化版)
        try:
            print("\n方法2: 使用 docx2pdf...")
            docx_to_pdf_convert(word_path, output_path)

            if os.path.exists(output_path) and os.path.getsize(output_path) > 1000:
                print("✓ docx2pdf转换成功")
                return output_path
        except Exception as e:
            print(f"✗ docx2pdf转换失败: {str(e)}")

        # 方法3: 使用 LibreOffice (如果安装)
        try:
            print("\n方法3: 尝试使用 LibreOffice...")
            import subprocess

            libreoffice_paths = [
                r'C:\Program Files\LibreOffice\program\soffice.exe',
                r'C:\Program Files (x86)\LibreOffice\program\soffice.exe',
                'soffice'
            ]

            for lo_path in libreoffice_paths:
                try:
                    # LibreOffice命令行转换
                    cmd = [
                        lo_path,
                        '--headless',
                        '--convert-to', 'pdf',
                        '--outdir', output_dir,
                        os.path.abspath(word_path)
                    ]

                    result = subprocess.run(cmd, capture_output=True, timeout=60)

                    if os.path.exists(output_path) and os.path.getsize(output_path) > 1000:
                        print("✓ LibreOffice转换成功")
                        return output_path
                except Exception:
                    continue
        except Exception as e:
            print(f"✗ LibreOffice转换失败: {str(e)}")

        # 所有方法都失败
        print("\n" + "=" * 60)
        print("✗ 转换失败: 所有方法都无法处理此Word文件")
        print("\n建议:")
        print("1. 安装 Microsoft Office (推荐，质量最佳)")
        print("2. 或安装 LibreOffice (免费替代)")
        print("3. 检查Word文档是否已损坏")
        print("=" * 60)

        raise Exception("Word转PDF失败：需要安装Microsoft Office或LibreOffice")

        return output_path

    def pdf_to_images(self, pdf_path, output_dir):
        """
        PDF转图片（每页一张）
        :param pdf_path: PDF文件路径
        :param output_dir: 输出目录
        :return: 输出文件路径列表
        """
        if not os.path.exists(pdf_path):
            raise FileNotFoundError(f"文件不存在: {pdf_path}")

        if not pdf_path.lower().endswith('.pdf'):
            raise ValueError(f"不是PDF文件: {pdf_path}")

        base_name = os.path.splitext(os.path.basename(pdf_path))[0]

        # 创建输出文件夹
        output_folder = os.path.join(output_dir, f"{base_name}_images")
        os.makedirs(output_folder, exist_ok=True)

        # 方法1: 尝试使用 pdf2image（需要Poppler）
        try:
            images = pdf2image.convert_from_path(pdf_path, dpi=200)

            if images:
                output_paths = []
                for i, image in enumerate(images, start=1):
                    output_path = os.path.join(output_folder, f"{base_name}_page_{i}.png")
                    image.save(output_path, 'PNG', optimize=True)
                    output_paths.append(output_path)
                return output_paths
        except Exception as e:
            print(f"pdf2image转换失败: {str(e)}，尝试备用方法...")

        # 方法2: 使用PyMuPDF (fitz) - 更快且不需要Poppler
        try:
            import fitz  # PyMuPDF

            doc = fitz.open(pdf_path)
            output_paths = []

            for page_num in range(len(doc)):
                page = doc.load_page(page_num)
                # 设置缩放以获得更高质量
                mat = fitz.Matrix(2.0, 2.0)  # 2x缩放
                pix = page.get_pixmap(matrix=mat)

                output_path = os.path.join(output_folder, f"{base_name}_page_{page_num + 1}.png")
                pix.save(output_path)
                output_paths.append(output_path)

            doc.close()

            if output_paths:
                print("使用PyMuPDF转换成功")
                return output_paths
        except ImportError:
            print("PyMuPDF未安装，尝试下一种方法...")
        except Exception as e:
            print(f"PyMuPDF转换失败: {str(e)}")

        # 如果所有方法都失败
        raise Exception("PDF转图片失败：所有转换方法都失败了。\n建议：\n1. 安装Poppler: 下载并添加到PATH\n2. 或安装PyMuPDF: pip install PyMuPDF\n3. 检查PDF是否已加密或损坏")

    def images_to_pdf(self, image_paths, output_dir):
        """
        多图合并为PDF
        :param image_paths: 图片文件路径列表
        :param output_dir: 输出目录
        :return: 输出PDF文件路径
        """
        if not image_paths:
            raise ValueError("图片列表为空")

        # 生成输出文件名
        output_path = os.path.join(output_dir, "merged_images.pdf")

        # 打开所有图片
        images = []
        for img_path in image_paths:
            try:
                img = Image.open(img_path)
                # 转换为RGB模式（PDF需要）
                if img.mode != 'RGB':
                    img = img.convert('RGB')
                images.append(img)
            except Exception as e:
                print(f"无法打开图片 {img_path}: {e}")

        if not images:
            raise ValueError("没有有效的图片文件")

        # 保存为PDF
        images[0].save(output_path, save_all=True, append_images=images[1:])

        return output_path

    def doc_to_docx(self, doc_path, output_dir):
        """
        DOC转DOCX
        :param doc_path: DOC文件路径
        :param output_dir: 输出目录
        :return: 输出文件路径
        """
        pythoncom.CoInitialize()
        try:
            base_name = os.path.splitext(os.path.basename(doc_path))[0]
            output_path = os.path.join(output_dir, f"{base_name}.docx")

            word = win32com.client.Dispatch("Word.Application")
            word.Visible = False
            doc = word.Documents.Open(os.path.abspath(doc_path))
            doc.SaveAs(os.path.abspath(output_path), FileFormat=16)  # 16 = DOCX格式
            doc.Close()
            word.Quit()

            return output_path
        finally:
            pythoncom.CoUninitialize()

    def docx_to_doc(self, docx_path, output_dir):
        """
        DOCX转DOC
        :param docx_path: DOCX文件路径
        :param output_dir: 输出目录
        :return: 输出文件路径
        """
        pythoncom.CoInitialize()
        try:
            base_name = os.path.splitext(os.path.basename(docx_path))[0]
            output_path = os.path.join(output_dir, f"{base_name}.doc")

            word = win32com.client.Dispatch("Word.Application")
            word.Visible = False
            doc = word.Documents.Open(os.path.abspath(docx_path))
            doc.SaveAs(os.path.abspath(output_path), FileFormat=0)  # 0 = DOC格式
            doc.Close()
            word.Quit()

            return output_path
        finally:
            pythoncom.CoUninitialize()
